#include "bitmap.h"
#include "string.h"

void bitmap_make(bitmap_t *map, char* bits, u32 length, u32 offset)
{
    map->bits = bits;
    map->length = length;
    map->offset = offset;
}

void bitmap_init(bitmap_t *map, char* bits, u32 length, u32 offset)
{
    memset(bits, 0, length);
    bitmap_make(map, bits, length, offset);
}

bool bitmap_test(bitmap_t *map, u32 index)
{
    u32 byte_index = (index + map->offset) / 8;
    u32 bit_index = (index + map->offset) % 8;
    return (map->bits[byte_index] & (1 << bit_index)) != 0;
}

void bitmap_set(bitmap_t *map, u32 index, bool value)
{
    u32 byte_index = (index + map->offset) / 8;
    u32 bit_index = (index + map->offset) % 8;
    if (value)
    {
        map->bits[byte_index] |= (1 << bit_index);
    } 
    else
    {
        map->bits[byte_index] &= ~(1 << bit_index);
    }
}

int bitmap_scan(bitmap_t *map, u32 count)
{
    int start = EOF;
    int remainBits = map->length * 8;
    int next_bit = 0;
    int counter = 0;
    while (remainBits--)
    {
        if (bitmap_test(map, map->offset + next_bit))
        {
            if (counter > 0) 
            {
                counter = 0;
                start = EOF;
            }
            next_bit++;
            continue;
        }

        if (counter == 0)
        {
            start = next_bit;
        }
        counter++;
        if (counter >= count)
        {
            break;
        }
        next_bit++;
    }
    if (counter < count)
    {
        return EOF;
    }

    for (int i = 0; i < count; i++)
    {
        bitmap_set(map, map->offset + start + i, true);
    }
    
    return start + map->offset;
}

